package com.youxin.logprocess.controller;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;

import com.youxin.busfoundation.bean.MonitorEmailBean;
import com.youxin.busfoundation.bean.MonitorSmsBean;
import com.youxin.busfoundation.config.MonitorAlarmConfig;
import com.youxin.busfoundation.config.MonitorBaseBean;
import com.youxin.busfoundation.email.EmailController;
import com.youxin.busfoundation.sms.SmsUtils;
import com.youxin.foundation.utils.DateUtil;
import com.youxin.foundation.utils.StringUtils;
import com.youxin.foundation.utils.collections.CollectionsUtils;
import com.youxin.foundation.utils.thread.BaseThreadPool;
import com.youxin.logprocess.bean.MessageBean;
import com.youxin.logprocess.common.MonitorGlobalConfig;

import scala.reflect.internal.Trees.If;

/**
 * 基础控制器
 * 
 * @author yingde.cao
 *
 */
public abstract class BaseMonitorController {
	protected static Logger logger = Logger.getLogger(BaseMonitorController.class);
	private Map<String, MessageBean> queues = Collections
			.synchronizedMap(new HashMap<>(MonitorGlobalConfig.DEFAULT_FAILURE_MAX_MESSAGE));
	/**
	 * 保存线上的统计数据,主要用于与Redis中的数据保持同步,不保证绝对同步
	 */
	private MonitorEmailBean emailBean;
	private MonitorSmsBean smsBean;

	/**
	 * 获取邮件信息
	 * 
	 * @return
	 */
	public MonitorEmailBean getEmailBean() {
		if (emailBean == null) {
			this.emailBean = MonitorAlarmConfig.instance().getAlarm().getEmail();
			/**
			 * 当前组的AlarmBean配置
			 */
			if (getMonitorBean().getAlarm() != null) {
				MonitorEmailBean tBean = getMonitorBean().getAlarm().getEmail();
				if (tBean != null) {
					if (!StringUtils.isNullOrEmpty(tBean.getTo())) {
						this.emailBean.setTo(tBean.getTo());
					}
					if (!StringUtils.isNullOrEmpty(tBean.getCc())) {
						this.emailBean.setCc(tBean.getCc());
					}
				}
			}

		}
		return emailBean;
	}

	/**
	 * 获取短信联系人信息
	 * 
	 * @return
	 */
	public MonitorSmsBean getSmsBean() {
		if (smsBean == null) {
			this.smsBean = MonitorAlarmConfig.instance().getAlarm().getSms();
			if (getMonitorBean().getAlarm() != null) {
				MonitorSmsBean tBean = getMonitorBean().getAlarm().getSms();
				if (!StringUtils.isNullOrEmpty(tBean.getPhones())) {
					this.smsBean.setPhones(tBean.getPhones());
				}
			}
		}
		return smsBean;
	}

	/**
	 * monitor config的id名称必须唯一
	 * 
	 * @return String
	 */
	public abstract MonitorBaseBean getMonitorBean();

	public void add(List<MessageBean> messageBeans) {
		for (MessageBean item : messageBeans) {
			add(item);
		}
	}

	/**
	 * 添加元素,方法添加锁
	 * 
	 * @param messageBean
	 */
	public void add(MessageBean messageBean) {
		try {
			if (queues.size() >= MonitorGlobalConfig.DEFAULT_FAILURE_MAX_MESSAGE) {
				return;
			}
			synchronized (this) {
				queues.put(messageBean.getHosts(), messageBean);
			}
		} catch (Exception e) {
			logger.error("添加Message异常", e);
		}
	}

	/**
	 * 推出所有元素,加锁
	 * 
	 * @return
	 */
	public synchronized List<MessageBean> popAll() {
		if (queues.size() == 0) {
			return new ArrayList<>();
		}
		Map<String, MessageBean> map = new HashMap<>(queues);
		queues.clear();
		return new ArrayList<>(map.values());
	}

	public void add(String host, String msg) {
		add(new MessageBean(host, msg));
	}

	public void add(String host, Exception e) {
		add(new MessageBean(host, getStackTrace(e)));
	}

	public void add(String[] hosts, Exception e) {
		for (String host : hosts) {
			add(host, e);
		}
	}

	public void adds(String hosts, Exception e) {
		String[] hostList = hosts.split(",", 0);
		add(hostList, e);
	}

	private String getSmsTitle(String title) {
		return title.length() > MonitorGlobalConfig.SMS_MESSAGE_LENGTH
				? title.substring(0, MonitorGlobalConfig.SMS_MESSAGE_LENGTH) : title;
	}

	protected void sendMessages(List<MessageBean> beans) {
		List<String> subjects = beans.stream().map(item -> item.getHosts()).collect(Collectors.toList());
		List<String> messages = beans.stream().map(item -> item.getMessage()).collect(Collectors.toList());
		String subject = getMonitorBean().getId() + "异常;" + CollectionsUtils.join(subjects, ",");
		String message = "详细信息如下:\n" + CollectionsUtils.join(messages, "\n\n");
		sendMessages(subject, message);
		logger.warn(
				"--------------------------------------------------- 发送邮件短信 ---------------------------------------------------");

	}

	/**
	 * 发送邮件和短信
	 * 
	 * @param subject
	 *            主题
	 * @param content
	 *            内容
	 */
	protected void sendMessages(String subject, String content) {
		try {
			BaseThreadPool.addTask(new Runnable() {
				@Override
				public void run() {
					try {
						EmailController emailController = new EmailController(getEmailBean());
						emailController.sendMessage(subject, content);
					} catch (Exception e) {
						logger.error("发送邮件失败", e);
					}
					String title = "";
					try {
						title = getSmsTitle(subject);
						String phones=getSmsBean().getPhones();
						String tSubject=getSmsTitle(subject);
						String result = SmsUtils.sendSms(phones,tSubject);
						logger.warn("发送短信到"+phones+",短信内容:"+tSubject+",返回:" + result);
					} catch (Exception e) {
						logger.error("发送短信失败:" + title + ",", e);
					}

				}
			});

		} catch (Exception e) {
			logger.error("发送信息失败", e);
		}
	}

	/**
	 * 获取堆栈详细信息
	 * 
	 * @param t
	 * @return
	 */
	private static String getStackTrace(Throwable t) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		try {
			t.printStackTrace(pw);
			return sw.toString();
		} finally {
			try {
				sw.close();
				pw.close();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
}
